﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using Newtonsoft.Json;
using SIE.SCADA.Common.Log;
using SIE.SCADA.StationDemo.Abstract;
using SIE.SCADA.Common;
using SIE.SCADA.StationDemo.Common;
using System.Text.RegularExpressions;
#if NET45
using System.IO.Ports;
#endif


namespace SIE.SCADA.StationDemo.SerialCommunicat
{
#if NET45
    class WinScannDevice : WorkerBase
    {
        private SerialPort csp = null;
        private string[] serailports;
        private string selectedComPort = "";
        private bool _isRunning;
        private readonly int baudRate = 9600;
        private string _portName;
        private readonly string start = "\u0002";
        private readonly string end = "\u0003";
        private readonly string spac = "\u0000";
        StringBuilder sb = new StringBuilder();
        public event EventHandler<BarcodeArg> ReceveChanged;

        public WinScannDevice(string portName)
        {
            _portName = portName;
        }

        protected override bool Init()
        {
            return true;
        }

        private bool Load(string fileName)
        {
            return true;
        }

        public override void Start()
        {
            ShowPortNames();
            if (string.IsNullOrEmpty(_portName)) return;
            csp = new SerialPort(_portName, baudRate);
            CloseUart(csp);
            csp.DataReceived += Csp_DataReceived;// Csp_DataReceived;
            try
            {
                csp.Open();
                Logger.Info($"-----Service Open Uart [{_portName}] Succful!-----");
            }
            catch (Exception ex)
            {
                Logger.Info($"------RunService Open Uart [{_portName}] Exception:{ex}------");
            }
        }

        public void WriteBarcode(string msg)
        {
            try
            {
                var send = start + msg + end;
                csp?.WriteLine(send);
                Logger.Info($"转发数据{send}");
            }
            catch (Exception ex)
            {
                Logger.Warn($"端口写入数据失败{ex.Message}");
            }
        }

        private void Csp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //new Thread(() =>
            //{
                var serialPort = sender as SerialPort;
                Thread.Sleep(100);
                // 获取字节长度
                int bytesNum = serialPort.BytesToRead;
                if (bytesNum == 0)
                    return;
                // 创建字节数组
                byte[] resultBuffer = new byte[bytesNum];
                serialPort.Read(resultBuffer, 0, bytesNum);
                try
                {
                    string msg = Encoding.ASCII.GetString(resultBuffer);
                    //Logger.Info($"----接收数据{msg}");
                    if (msg.Contains(start) && msg.Contains(end))
                    {
                        Regex regex = new Regex($@"(?<={start}).*?(?={end})");
                        var resMsg = regex.Match(msg).Value;
                        resMsg = resMsg.Replace(spac, "");
                        ReceveChanged.Invoke(this, new BarcodeArg(resMsg));
                        string echo = $"{serialPort.PortName} Receive Data:[{resMsg}]-------------";
                        Logger.Info($"{echo}");
                    }
                    else
                    {
                        if(msg.Contains(start))
                        {
                            sb = new StringBuilder();
                            sb.Append(msg);
                        }
                        else if(msg.Contains(end))
                        {
                            sb.Append(msg);
                            var contact = sb.ToString();
                            Regex regex = new Regex($@"(?<={start}).*?(?={end})");
                            var resMsg = regex.Match(contact).Value;
                            resMsg = resMsg.Replace(spac,"");
                            ReceveChanged.Invoke(this, new BarcodeArg(resMsg));
                            string echo = $"{serialPort.PortName} Receive Data:[{resMsg}]-----------";
                            Logger.Info($"{echo}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex.Message);
                }
            //}).Start();
        }

        private void ShowPortNames()
        {
            //Logger.Info($"This computer has {serailports.Length} serial ports.");
            //foreach (string serial in serailports)
            //    Logger.Info($"serial port:{serial}");
        }

        private void CloseUart(SerialPort port)
        {
            if (port != null)
            {
                port.DataReceived -= Csp_DataReceived;//Csp_DataReceived;
                if (csp.IsOpen)
                {
                    csp.Close();
                    csp.Dispose();
                }
                port = null;
                Logger.Info($"close serial port:{selectedComPort} succful!");
            }
        }

        public override void Stop()
        {
            CloseUart(csp);
        }

        protected override bool Load()
        {
            return true;
        }

        public string PortName { get; set; }
        public override bool IsRunning { get; set; }
    }
#endif
}
